package define

import (
	"crypto/md5"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/jordan-wright/email"
	"github.com/shopspring/decimal"
	"math/rand"
	"net/smtp"
	"regexp"
	"strconv"
	"time"
)

// 生成token
type UserClaims struct {
	UserId    int    `json:"user_id"`
	Phone     string `json:"phone"`
	CreatedAt int64  `json:"created_at"`
	jwt.StandardClaims
}

var mykey = []byte("uniappMy")

func GenerateToken(userId int, Phone string) (string, error) {
	UserClaim := UserClaims{
		UserId:         userId,
		Phone:          Phone,
		CreatedAt:      time.Now().Unix(),
		StandardClaims: jwt.StandardClaims{},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaim)
	tokenString, err := token.SignedString(mykey)
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// 解析token
func AnalyseToken(tokenString string) (*UserClaims, error) {
	UserClaim := new(UserClaims)
	claim, err := jwt.ParseWithClaims(tokenString, UserClaim, func(token *jwt.Token) (interface{}, error) {
		return mykey, nil
	})
	if err != nil {
		return nil, err
	}
	if !claim.Valid {
		return nil, fmt.Errorf("Analyse token Error:%v", err)
	}
	return UserClaim, nil
}

// 生成MD5
func GetMD5(s string) string {
	return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}

// @Title md5加密
func MD5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

// 时间格式转时间戳
func TimeUnix(n string) int64 {
	timeLayout := "2006-01-02 15:04:05"
	timeStamp, _ := time.ParseInLocation(timeLayout, n, time.Local)
	timeStampU := timeStamp.Unix()
	return timeStampU
}

// 随机数字串
func RandomNum(leng int) string {
	//定义变量
	result := ""
	//获取当前时间戳
	rand.Seed(time.Now().UnixNano())
	//for循环取指定的位数
	for i := 0; i < leng; i++ {
		num := rand.Intn(10)
		result = result + strconv.Itoa(num)
	}
	return result
}

// 生成邀请码
const (
	KC_RAND_KIND_NUM   = 0 // 纯数字
	KC_RAND_KIND_LOWER = 1 // 小写字母
	KC_RAND_KIND_UPPER = 2 // 大写字母
	KC_RAND_KIND_ALL   = 3 // 数字、大小写字母
)

func Krand(size int, kind int) []byte { // 随机字符串
	ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
	is_all := kind > 2 || kind < 0
	rand.Seed(time.Now().UnixNano())
	for i := 0; i < size; i++ {
		if is_all { // random ikind
			ikind = rand.Intn(3)
		}
		scope, base := kinds[ikind][0], kinds[ikind][1]
		result[i] = uint8(base + rand.Intn(scope))
	}
	return result
}

// 验证邮箱
func VerifyEmailFormat(email string) bool {
	//邮箱的正则
	pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$`
	// 正则调用规则
	reg := regexp.MustCompile(pattern)
	// 返回 MatchString 是否匹配
	return reg.MatchString(email)
}

// 调用邮箱接口
func EmailCode(toemail string, subject string, body string) error {
	e := email.NewEmail()
	//发送邮箱
	e.From = "Mericama <service003@mericama.com>"
	//发送目标
	e.To = []string{toemail}
	//标题
	e.Subject = subject
	//发送内容
	e.HTML = []byte(body)
	//返回EOF时，关闭SSL连接重试
	return e.SendWithTLS("smtphz.qiye.163.com:465",
		smtp.PlainAuth("", "service003@mericama.com", "h53MbZwfcyFt4gSy", "smtphz.qiye.163.com"),
		&tls.Config{InsecureSkipVerify: true, ServerName: "smtphz.qiye.163.com"})
	//return e.SendWithTLS("smtp.gmail.com:465",
	//	smtp.PlainAuth("", "mericamacom@gmail.com", "tjhizvgqlvgxmsyg", "smtp.gmail.com"),
	//	&tls.Config{InsecureSkipVerify: true, ServerName: "smtp.gmail.com"})
	//return e.SendWithTLS("smtp.gmail.com:465",
	//	smtp.PlainAuth("", "loujianming0015@gmail.com", "vacpsjhjgjlzctjb", "smtp.gmail.com"),
	//	&tls.Config{InsecureSkipVerify: true, ServerName: "smtp.gmail.com"})
}

// 保留4位小数
func SprintfS(n float64) float64 {
	s := fmt.Sprintf("%0.2f", n)      //保留4为小数
	f, _ := strconv.ParseFloat(s, 64) //字符串转为浮点数64
	return f
}

// 随机数
func Random(min, max int) int {
	return rand.Intn(max-min) + min
}

// 手机号中间4位替换为*号
func FormatMobileStar(mobile string) string {
	if len(mobile) <= 10 {
		return mobile
	}
	return mobile[:3] + "****" + mobile[len(mobile)-4:]
}

// 将数组中的数据全部转为字符串
func ArrayToString(arr []int) string {
	var result string
	for i := 0; i < len(arr); i++ {
		if i == 0 {
			result += strconv.Itoa(arr[i])
		} else {
			result += "," + strconv.Itoa(arr[i])
		}
	}
	return result
}

// 加法decimal
func AddDecimal(d1 decimal.Decimal, d2 decimal.Decimal) decimal.Decimal {
	return d1.Add(d2)
}

// 减法decimal
func SubDecimal(d1 decimal.Decimal, d2 decimal.Decimal) decimal.Decimal {
	return d1.Sub(d2)
}

// 乘法decimal
func MulDecimal(d1 decimal.Decimal, d2 decimal.Decimal) decimal.Decimal {
	return d1.Mul(d2)
}

// 除法decimal
func DivDecimal(d1 decimal.Decimal, d2 decimal.Decimal) decimal.Decimal {
	return d1.Div(d2)
}

// decimal转int
func IntDecimal(d decimal.Decimal) int64 {
	return d.IntPart()
}

// decimal转float
func FloatDecimal(d decimal.Decimal) float64 {
	f, exact := d.Float64()
	if !exact {
		return f
	}
	return f
}

// 巴西时间
func BaXiTime() (int64, string) {
	cur, _ := time.LoadLocation("America/Sao_Paulo")
	curs := time.Now().In(cur).Format("2006-01-02 15:04:05")
	curss := TimeUnix(curs)
	return curss, curs
}
